package com.auth.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;

@Configuration
@RefreshScope
public class RedisConfiguration {

    private final static Logger log  = LoggerFactory.getLogger(RedisConfiguration.class);

    @Value("${spring.redis.jedis.pool.max-idle}")
    private  Integer maxIdle;

    @Value("${spring.redis.jedis.pool.min-idle}")
    private  String minIdle;

    @Value("${spring.redis.jedis.pool.max-active}")
    private  String maxActive;

    @Value("${spring.redis.jedis.pool.max-wait}")
    private  Integer maxWait;

    @Value("${spring.redis.jedis.pool.max-total}")
    private Integer maxTotal;

//    @Value("${spring.redis.jedis.pool.minEvictableIdleTimeMillis}")
//    private Integer minEvictableIdleTimeMillis;
//
//    @Value("${spring.redis.jedis.pool.numTestsPerEvictionRun}")
//    private Integer numTestsPerEvictionRun;
//
//    @Value("${spring.redis.jedis.pool.timeBetweenEvictionRunsMillis}")
//    private long timeBetweenEvictionRunsMillis;
//
//    @Value("${spring.redis.jedis.pool.testOnBorrow}")
//    private boolean testOnBorrow;
//
//    @Value("${spring.redis.jedis.pool.testWhileIdle}")
//    private boolean testWhileIdle;

    @Value("${spring.redis.host}")
    private  String hostname;

    @Value("${spring.redis.password}")
    private  String password;

    @Value("${spring.redis.port}")
    private  Integer port;

    @Value("${spring.redis.timeout}")
    private  Integer timeout;


    @Bean
    public JedisPoolConfig jedisPoolConfig(){
        log.info(">>************************* start of [ redis link pool configuration ] of global configuration ");
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        // 最大空闲数
        log.info(">>========================maxIdle:{}======================<<",maxIdle);
        jedisPoolConfig.setMaxIdle(maxIdle);
        // 连接池的最大数据库连接数
        log.info(">>========================maxTotal:{}======================<<",maxTotal);
        jedisPoolConfig.setMaxTotal(maxTotal);
        // 最大建立连接等待时间
        jedisPoolConfig.setMaxWaitMillis(maxWait);
//        // 逐出连接的最小空闲时间 默认1800000毫秒(30分钟)
//        jedisPoolConfig.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
//        // 每次逐出检查时 逐出的最大数目 如果为负数就是 : 1/abs(n), 默认3
//        jedisPoolConfig.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
//        // 逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
//        jedisPoolConfig.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
//        // 是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个
//        jedisPoolConfig.setTestOnBorrow(testOnBorrow);
//        // 在空闲时检查有效性, 默认false
//        jedisPoolConfig.setTestWhileIdle(testWhileIdle);
        log.info("<<************************* end of [ redis link pool configuration ] of global configuration ");
        return jedisPoolConfig;
    }
    @Bean
    @Primary
    public JedisConnectionFactory jedisConnectionFactory(JedisPoolConfig jedisPoolConfig){
        log.info(">>************************* start of [ redis connection factory configuration ] of global configuration ");
        JedisConnectionFactory JedisConnectionFactory = new JedisConnectionFactory(jedisPoolConfig);
        //连接池
        JedisConnectionFactory.setPoolConfig(jedisPoolConfig);
        //IP地址
        log.info(">>========================hostname:{}======================<<",hostname);
        JedisConnectionFactory.setHostName(hostname);
        //端口号
        log.info(">>===========================port:{}==========================<<",port);
        JedisConnectionFactory.setPort(port);
        //如果Redis设置有密码
        JedisConnectionFactory.setPassword(password);
        //客户端超时时间单位是毫秒
        JedisConnectionFactory.setTimeout(timeout);
        log.info(">>************************* end of [ redis connection factory configuration ] of global configuration ");
        return JedisConnectionFactory;
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate(JedisConnectionFactory factory){
        // 解决 org.springframework.data.redis.serializer.SerializationException: Could not read JSON
        // 序列化方式不一样，旧的是通过StringRedisSerializer进行序列化的，springboot是通过Jackson2JsonRedisSerializer进行序列化
        RedisTemplate redisTemplate = new StringRedisTemplate(factory);
        StringRedisSerializer stringRedisSerializer =new StringRedisSerializer();
        redisTemplate.setValueSerializer(stringRedisSerializer);
        redisTemplate.setKeySerializer(stringRedisSerializer);
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        redisTemplate.setHashValueSerializer(stringRedisSerializer);
        redisTemplate.afterPropertiesSet();
        // 开启事务
        redisTemplate.setEnableTransactionSupport(true);
        redisTemplate.setConnectionFactory(factory);
        return redisTemplate;
    }

}